home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 June / PCWorld_2007-06_cd.bin / v cisle / tclock / tclocklight-040702-3.exe / source / exe / menu.c < prev    next >
C/C++ Source or Header  |  2004-09-07  |  8KB  |  311 lines

  1. /*-------------------------------------------------------------
  2.   menu.c : context menu of TClock
  3.   (C) 1997-2003 Kazuto Sato
  4.   Please read readme.txt about the license.
  5.   
  6.   Written by Kazubon, Nanashi-san
  7. ---------------------------------------------------------------*/
  8.  
  9. #include "tclock.h"
  10. #include "../common/command.h"
  11.  
  12. /* Globals */
  13.  
  14. void ContextMenuCommand(HWND hwnd, int id);
  15. void EndMenu(void);
  16. void OnContextMenu(HWND hwnd, HWND hwndClicked, int xPos, int yPos);
  17. void OnExitMenuLoop(HWND hwnd);
  18. void SetFocusTClockMain(HWND hwnd);
  19.  
  20. /* Statics */
  21.  
  22. typedef struct _tagMenuStruct
  23. {
  24.     int id;
  25.     char command[MAX_PATH];
  26. } MENUSTRUCT;
  27. typedef MENUSTRUCT* PMENUSTRUCT;
  28.  
  29. static void SendOnContextMenu(void);
  30. static void CheckMenu(HMENU hmenu);
  31. static void LoadMenuFromText(HMENU hmenu,
  32.     const char *fname, const WIN32_FIND_DATA *pfd);
  33. static int ReadMenuCommands(HMENU hmenu, const char *p,
  34.     PMENUSTRUCT pmenus);
  35.  
  36. static HMENU m_hMenu = NULL;
  37. static char m_tcmenutxt[MAX_PATH] = { 0 };
  38. static PMENUSTRUCT m_pmenuCommands = NULL;
  39. static int m_numCommands = 0;
  40. static DWORD m_lasttime = 0;
  41.  
  42. /*------------------------------------------------
  43.   open/execute a file with context menu
  44. --------------------------------------------------*/
  45. void ContextMenuCommand(HWND hwnd, int id)
  46. {
  47.     int i;
  48.     if(!m_pmenuCommands) return;
  49.     
  50.     for(i = 0; i < m_numCommands; i++)
  51.     {
  52.         if(id == m_pmenuCommands[i].id)
  53.         {
  54.             if(m_pmenuCommands[i].command[0])
  55.                 ExecCommandString(hwnd, m_pmenuCommands[i].command);
  56.             break;
  57.         }
  58.     }
  59. }
  60.  
  61. /*------------------------------------------------
  62.   clean up
  63. --------------------------------------------------*/
  64. void EndMenu(void)
  65. {
  66.     if(m_hMenu) DestroyMenu(m_hMenu);
  67.     m_hMenu = NULL;
  68.     if(m_pmenuCommands) free(m_pmenuCommands);
  69.     m_pmenuCommands = NULL;
  70. }
  71.  
  72. /*------------------------------------------------
  73.   when the clock is right-clicked
  74.   show pop-up menu
  75. --------------------------------------------------*/
  76. void OnContextMenu(HWND hwnd, HWND hwndClicked, int xPos, int yPos)
  77. {
  78.     WIN32_FIND_DATA fd;
  79.     HANDLE hfind;
  80.     
  81.     SendOnContextMenu();
  82.     
  83.     if(m_tcmenutxt[0] == 0 || !IsFile(m_tcmenutxt))
  84.     {
  85.         // common/tclang.c
  86.         FindFileWithLangCode(m_tcmenutxt, GetUserDefaultLangID(), TCMENUTXT);
  87.     }
  88.     
  89.     hfind = FindFirstFile(m_tcmenutxt, &fd);
  90.     if(hfind != INVALID_HANDLE_VALUE)
  91.     {
  92.         FindClose(hfind);
  93.         if(m_lasttime != fd.ftLastWriteTime.dwLowDateTime)
  94.         {
  95.             EndMenu();
  96.             m_lasttime = fd.ftLastWriteTime.dwLowDateTime;
  97.         }
  98.     }
  99.     else m_lasttime = 0;
  100.     
  101.     // create popup menu and append items from tcmenu.txt
  102.     if(!m_hMenu)
  103.     {
  104.         m_hMenu = CreatePopupMenu();
  105.         if(hfind != INVALID_HANDLE_VALUE)
  106.             LoadMenuFromText(m_hMenu, m_tcmenutxt, &fd);
  107.         else
  108.             LoadMenuFromText(m_hMenu, NULL, NULL);
  109.     }
  110.     
  111.     CheckMenu(m_hMenu);
  112.     
  113.     // get keyboard input
  114.     SetFocusTClockMain(hwnd);
  115.     
  116.     // open popup menu
  117.     TrackPopupMenu(m_hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON,
  118.         xPos, yPos, 0, hwnd, NULL);
  119. }
  120.  
  121. /*------------------------------------------------
  122.   WM_EXITMENULOOP message
  123. --------------------------------------------------*/
  124. void OnExitMenuLoop(HWND hwnd)
  125. {
  126.     HWND hwndBar;
  127.     DWORD pid, clockthread, mythread;
  128.     
  129.     hwndBar = GetTaskbarWindow();
  130.     if(hwndBar)
  131.     {
  132.         clockthread = GetWindowThreadProcessId(hwndBar, &pid);
  133.         mythread = GetCurrentThreadId();
  134.         AttachThreadInput(clockthread, mythread, TRUE);
  135.         SetFocus(hwndBar);
  136.         AttachThreadInput(clockthread, mythread, FALSE);
  137.     }
  138. }
  139.  
  140. /*------------------------------------------------
  141.   set keyboard focus to the main window forcely
  142. --------------------------------------------------*/
  143. void SetFocusTClockMain(HWND hwnd)
  144. {
  145.     DWORD pid, curthread, mythread;
  146.     
  147.     curthread = GetWindowThreadProcessId(GetForegroundWindow(), &pid);
  148.     mythread = GetCurrentThreadId();
  149.     AttachThreadInput(mythread, curthread, TRUE);
  150.     SetFocus(hwnd);
  151.     AttachThreadInput(mythread, curthread, FALSE);
  152. }
  153.  
  154. /*------------------------------------------------
  155.   tell other programs
  156.   that right-click menu is to open
  157. --------------------------------------------------*/
  158. void SendOnContextMenu(void)
  159. {
  160.     HWND hwndProg;
  161.     char entry[20], buf[100], cname[80], num[20];
  162.     int i, msg;
  163.     
  164.     for(i = 0; ; i++)
  165.     {
  166.         wsprintf(entry, "App%d", i + 1);
  167.         GetMyRegStr("OnContextMenu", entry, buf, 100, "");
  168.         if(!buf[0]) break;
  169.         
  170.         parse(cname, buf, 0, 80);
  171.         if(!cname[0]) continue;
  172.         parse(num, buf, 1, 20);
  173.         if(!num[0]) continue;
  174.         msg = atoi(num);
  175.         
  176.         hwndProg = FindWindow(cname, NULL);
  177.         if(hwndProg)
  178.             SendMessage(hwndProg, msg, 0, 0);
  179.     }
  180. }
  181.  
  182. /*------------------------------------------------
  183.   enable/disable menu item
  184. --------------------------------------------------*/
  185. void CheckMenu(HMENU hmenu)
  186. {
  187.     char s[80];
  188.     int winver = CheckWinVersion();
  189.     
  190.     EnableMenuItem(hmenu, IDC_TASKMAN, MF_BYCOMMAND|
  191.         ((winver&WINNT) ? MF_ENABLED:MF_GRAYED) );
  192.     
  193.     EnableMenuItem(hmenu, IDC_SYNCTIME, MF_BYCOMMAND|
  194.         (GetMyRegStr("SNTP", "Server", s, 80, "") > 0 ?
  195.             MF_ENABLED:MF_GRAYED));
  196. }
  197.  
  198. /*------------------------------------------------
  199.   read menu commands from tcmenu*.txt
  200. --------------------------------------------------*/
  201. void LoadMenuFromText(HMENU hmenu,
  202.     const char *fname, const WIN32_FIND_DATA *pfd)
  203. {
  204.     HFILE hf = HFILE_ERROR;
  205.     int size;
  206.     char *pbuf;
  207.     
  208.     if(fname && pfd)
  209.         hf = _lopen(fname, OF_READ);
  210.     if(hf == HFILE_ERROR)
  211.     {
  212.         AppendMenu(hmenu, MF_STRING, IDC_EXIT, "Exit TClock");
  213.         return;
  214.     }
  215.     
  216.     size = (int)pfd->nFileSizeLow;
  217.     pbuf = malloc(size + 1);
  218.     _lread(hf, pbuf, size);
  219.     pbuf[size] = 0;
  220.     _lclose(hf);
  221.     
  222.     m_numCommands = ReadMenuCommands(NULL, pbuf, NULL);
  223.     
  224.     if(m_pmenuCommands) free(m_pmenuCommands);
  225.     m_pmenuCommands = NULL;
  226.     
  227.     if(m_numCommands > 0)
  228.         m_pmenuCommands = malloc(sizeof(MENUSTRUCT) * m_numCommands);
  229.     ReadMenuCommands(hmenu, pbuf, m_pmenuCommands);
  230.     
  231.     free(pbuf);
  232. }
  233.  
  234. /*------------------------------------------------
  235.   add commands to MENUSTRUCT and HMENU
  236. --------------------------------------------------*/
  237. int ReadMenuCommands(HMENU hmenu, const char *p,
  238.     MENUSTRUCT* pmenus)
  239. {
  240.     int count = 0;
  241.     int idCommand = 1;
  242.     char name[81], command[MAX_PATH];
  243.     
  244.     while(*p)
  245.     {
  246.         if(*p == '#' ||
  247.             *p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
  248.         {
  249.             p = nextline(p);
  250.         }
  251.         else if(*p == '-' && *(p + 1) == '-')
  252.         {
  253.             if(hmenu)
  254.                 AppendMenu(hmenu, MF_SEPARATOR, 0, 0);
  255.             p = nextline(p);
  256.         }
  257.         else
  258.         {
  259.             BOOL bdigit;
  260.             int id, i;
  261.             char quot;
  262.             
  263.             quot = 0;
  264.             if(*p == '\"' || *p == '\'') { quot = *p; p++; }
  265.             for(i = 0; i < 80 &&
  266.                 *p && *p != '\r' && *p != '\n'; i++)
  267.             {
  268.                 if(quot) { if(*p == quot) { p++; break; } }
  269.                 else if(*p == ' ' || *p == '\t') break;
  270.                 name[i] = *p++;
  271.             }
  272.             name[i] = 0;
  273.             while(*p == ' ' || *p == '\t') p++;
  274.             
  275.             quot = 0;
  276.             if(*p == '\"' || *p == '\'') { quot = *p; p++; }
  277.             for(i = 0; i < MAX_PATH-1 &&
  278.                 *p && *p != '\r' && *p != '\n'; i++)
  279.             {
  280.                 if(quot && *p == quot) break;
  281.                 command[i] = *p++;
  282.             }
  283.             command[i] = 0;
  284.             
  285.             bdigit = isdigitstr(command);
  286.             if(bdigit) id = atoi(command);
  287.             else id = idCommand;
  288.             
  289.             if(hmenu)
  290.                 AppendMenu(hmenu, MF_STRING, id, name);
  291.             
  292.             if(!bdigit)
  293.             {
  294.                 if(pmenus)
  295.                 {
  296.                     pmenus[count].id = id;
  297.                     strcpy(pmenus[count].command, command);
  298.                 }
  299.                 count++;
  300.                 if(count >= 50) return count;
  301.                 idCommand++;
  302.             }
  303.             
  304.             p = nextline(p);
  305.         }
  306.     }
  307.     
  308.     return count;
  309. }
  310.  
  311.